<?php

/**
 * Zakladni jednotka ve stromu databaze, kterou je treba podedit
 */

class tStandard_TreeItem extends cNode 
{
	public $data = null;
	public $definition = null;
	public $documentElement = null;

	public $order = "lft";
	
	static $definitionCache;
	
	/**
	 * Konstruktor
	 */
	function __construct(cCms $cms, $data=null, simpleXML $XMLdef = null)
	{	
		//	zavoláme taťkův konstruktor	
		parent::__construct($cms);
		
			
		$this->setDefinition($XMLdef);
		$this->setData($data);
		
		if ($this->getStandard('type')=='' || $this->getStandard('group')=='') 
		{
			$chunks = explode("_",get_class($this));
			$this->setStandard('group', strToLower(substr($chunks[0],1)));
			$this->setStandard('type', strToLower($chunks[1]));			
		}
		
		//	událost
		$this->onLoad();
		$this->cms->debugger->log('initialised',$this);
	}
	
	function onLoad() 
	{
	}
	
	function setDefinition($def = null) 
	{
		if ($def === null) return;
		if ($def instanceof SimpleXMLElement) 
		{
			$this->definition = $def;
		} else $this->definition = simplexml_load_string($def);

		//Event
		$this->onDefinitionSet();	
		
		$this->documentElement = new cPart($def, $this);
		//Event
		$this->onPartsLoad();	
	}
	
	function onPartsLoad()
	{
	}
	
	function onDefinitionSet()
	{
	}
	
		/**
		 *	Vrátí defaultní hodnotu domu
		 */
		function getDefaultDom() 
		{
			$dom = new DomDocument();
			$s=$dom->createElement("standard");
			$s->appendChild($dom->createElement("type",$this->type));
			$s->appendChild($dom->createElement("group",$this->group));
		
			$r=$dom->createElement("node");
			$r->appendChild($s);
			$dom->appendChild($r);
			return $dom;
		}
	
		/**
		 * Sežene definici domu
		 */
		function getDefinition(cView $view = null) 
		{
			$definition = null;
			$sxml = null;
			$nodes = $this->getTables();

			// onFly Cache
			if ($this->cms->onFlyCache['definition'][$this->group][$this->type] instanceof SimpleXMLElement) 
			{
				return self::$this->cms->onFlyCache['definition'][$this->group][$this->type];
			}
			
			foreach ($nodes as $n) 
			{
				$info = explode('_',$n);
				
				if ($sxml!==null) {
					$s = $this->cms->file->getDefinitionXML($info[0], $info[1]);
					//echo $s."<br><br><br>\n\n\n";
					$extension = simplexml_load_string($s = ''.$s.'');
					$sxml = $this->extendDefinition($sxml, $extension);
				} else {
					$s = $this->cms->file->getDefinitionXML($info[0], $info[1]);
					//echo $s."<br><br><br>\n\n\n";
					$sxml = simplexml_load_string($s =''.($s).'');
				}

			}
			
			// onFly Cache
			$this->cms->onFlyCache['definition'][$this->group][$this->type] = $sxml;
			
			//echo $sxml->asXML();
			
			return $sxml;
		}
			/**
			 *	"podědí" xml definici
			 */	
		private function extendDefinition(SimpleXMLElement $e1, SimpleXMLElement $e2) 
		{
			$root = $e1->getName();
			$o = simpleXML_load_string('<'.$root.'></'.$root.'>');
			foreach ($e1->children() as $nodeDef)
			{
				$node = $this->importNode($nodeDef, $o, false);
				foreach ($nodeDef->children() as $defEl) 
				{
					if ($defEl['field']!='') 
					{
						$q = array();
						$replacement = $e2->xpath('/'.$root.'/'.$nodeDef->getName.'/*[@field="'.$defEl['field'].'"]');
						if ($replacement[0]['field']==$defEl['field']) 
						{
							$this->importNode($replacement[0], $node);
							continue;
						}
					}
					$this->importNode($defEl, $node);
				}
			}
			$last = $e2->xpath('//node[last()]');
			$this->importNode($last[0], $o);
			
			return $o;
		}

		private function importNode($node, $dest, $recursive=true) 
		{
			$child = $dest->addChild($node->getName(), (string) $node);
			foreach ($node->attributes() as $key=>$val) 
			{
				if ($key!='' && $val!='')
				$child->addAttribute($key, $val);
			}
			if ($recursive) 
			{
				foreach ($node->children() as $n) 
				{
					$this->importNode($n, $child, $recursive);
				}
			}
			return $child;
		}
		

	/**
	 * Po nacteni dat
	 */
	function onDataLoad() 
	{
		if ($this->data->standard_treeitem)
		foreach ($this->data->standard_treeitem->children() as $key => $val) {
			$this->{$key} = (string) $val;
		}
	}

	/**
	 * Vrátí jména tabulek pro select/zapisování
	 */	
	function getTables() 
	{
    	$class = $this;
    	$tables[]=strtolower(substr(get_class($this),1));
	    while ((string)($class = get_parent_class($class))!='cNode' && $class!='') { 
	    	$oName = strtolower(substr($class,1));
   	  		$tables[] = $this->cms->tree->prefix.$oName;
	    } 
	    $tables = array_reverse($tables);
	    return $tables;		
    }


	function getTranslated($path) {
		return "nic";
	}
	
	/* =========================================== */
	/* ----------------- události ---------------- */
	/* =========================================== */
	
	function beforeSave() 
	{
		// pokud nebudem insertovat
		if (is_numeric($this->id)) 
		{
			$table=strToLower($this->cms->tree->prefix."standard_treeitem");
			$old = mysql_fetch_array($this->cms->tree->query("SELECT * FROM `$table` WHERE id=".$this->id));
			
			//koren nepresouvat
			if ($old['lft']!='1' && $this->parent_id!=$old['parent_id']) 
			{
				$actions[]='move';
				$this->_move($old,$this->parent_id);
			}
		} else 	$actions[]='insert';
		
		
		$now = date("Y-m-d H:i:s");
		
		//	cas zmeny
		$this->data->standard_treeitem->changed_at = $now; 

		// cas stvoreni
		if (!isset($this->data->standard_treeitem->id)) {
			$this->setStandard('created_at',$now);
		} else $this->setStandard('created_at',$old['created_at']);
		

		// autor
		$aID = ((string)$this->data->standard_treeitem->author_id);
		if (is_numeric($aID) && $aID!=0) 
		{
			$this->setStandard('author_id',$old['author_id']);
		}

		if ($this->author_id==$this->cms->user->id && !$this->cms->user->anonymous) 
		{
			$actions[]='write';
		} else $actions[]='write+';


		// viditelnost
		if (((string)$this->data->standard_treeitem->visibility)=='') {
			$this->setStandard('visibility',$old['visibility']);
		}

		if ((string)$this->data->standard_treeitem->visibility=='') {
			$this->setStandard('visibility','not-published');
		}

		if ($old['visibility']!='published'
			&& ((string)$this->data->standard_treeitem->visibility)=='published') 
		{
			$actions[]='publish';
			$this->setStandard('published_at',$now);
		}

		// string id se pouziva v odkazech
		$this->data->standard_treeitem->string_id = $this->makeStringId($this);	

		//	kontrola prav
		if (!$this->cms->user->hasPermissionFor($actions, $this)) {
			throw new cException('Pro akci nemáte dostatečné oprávnění', $this);
		}
	}
	
	function afterSave()
	{
	}
	
	
	function beforeUpdate()
	{
	}
	function afterUpdate()
	{
	}

	function beforeDelete()
	{
		//	kontrola prav
		if (!$this->cms->user->hasPermissionFor(array('change'), $this)) {
			throw new cException('Pro akci nemáte dostatečné oprávnění', $this);
		}
	}
	function afterDelete()
	{
	}
	
	/**
	 * Když jsme novým prvkem ve stromu, vložíme se, abychom pak mohli provést stejné sql čachry - tedy update
	 */
	function beforeInsert() 
	{
		$parent = $this->cms->tree->selectRaw("id=".$this->parent_id);
		$this->cms->nstree->newFirstChild($parent[0]); //inserts space
				
		$this->setStandard('id',mysql_insert_id($this->cms->link));
		$this->setStandard('lft', $parent[0]["lft"]+1);
		$this->setStandard('rgt', $parent[0]["lft"]+2);

		$this->data->standard_treeitem->author_id = $this->cms->user->id;

		$table = $this->getTables();
		array_shift($table);		
		foreach ($table as $t) 
		{
			$this->cms->tree->query('INSERT INTO '.$this->cms->tree->prefix.$t.' SET `id`='.$this->id);
		}
	}

	/* =========================================== */
	/* ---- implementace abstraktních metod ------ */
	/* =========================================== */

		/* ========================== */
		/* ---- informace o node ---- */
		/* ========================== */

		/** zobrazí node v daném pohledu */
		function view(cView $view)
		{	
			$this->cms->debugger->log('viewing',$this);
			
			$this->complete($view);			
			
			$this->beforeView();
			
			//získání elementu a posléze domu
			
			$sxml = $this->getSXML($this->data, $view);
			
			
			$dom_sxe = dom_import_simplexml($sxml);
			
			$dom = new DOMDocument('1.0','utf-8');
			$dom_sxe = $dom->importNode($dom_sxe, true);
			$dom_sxe = $dom->appendChild($dom_sxe);
			
			//$dom->formatOutput = true;
			//echo $dom->saveXML();
			
			try {
				$xsl=$this->getXsl($view);
				$text = $xsl->transformToXML($dom);
			} catch (Exception $e) { throw $e; }
	
			$text = html_entity_decode($text);
			if (1 OR $view->length!='full') return htmlspecialchars($text);
			return $text;
		}
	
		function beforeView() {
			
		}
		
		/** Vrátí šablonu */
		function getXsl($view) {
			return $this->cms->file->getXsl($this->group,$this->type,$view);
		}	
	
	
		function numSubNodes($node) {
			
    		return ($this->rgt-$this->lft-1)/2;
		}

		function hasChildren() 
		{
	    	return ($this->rgt-$this->lft-1)>0;
		}

		/**
		 * Vrátí XML s filtry (pouze mé, pouze od výrobce ABC, pouze na skladě..)
		 */
		function getFilters()
		{
			
		}


		/* ================================ */
		/* -------- relativní gety -------- */
		/* ================================ */

		function getPrior()
		{
		}
		
		function getNext()
		{
		}
	
		function getParent()
		{
			if ($this->parent_id == null) return null;
			$p = $this->cms->tree->getNodes("id=".$this->parent_id);
			return $p[0];
		}
	
		function getFirst()
		{
		}
		function getLast()
		{
		}

		/** Vrátí přímé potomky */
		function getChildren($view, &$sender=null) 
		{
			$where = "1";

			if ( $sender->order!="") {
				$order = $sender->order;
			} else if ($this->order!="") {
				$order = $this->order;
			} else $order = "lft";
			
			return $this->getChildrenWhere($where." ORDER BY ".$order, $view);
		}

		function getChildrenCount($view) 
		{
			if (is_numeric($this->id)) {
				return $this->cms->tree->getCount("parent_id=".$this->id, $view);
			} else return 0;
		}

		function getSubnodesCount($view) 
		{
			if (is_numeric($this->id)) {
				return $this->cms->tree->getCount("lft>".$this->lft." AND rgt<".$this->rgt, $view);
			} else return 0;
		}

		/** Vrátí všechny potomky */
		function getSubNodes($view)
		{
			return $this->getSubNodesWhere("1", $view);
		}
	
		/** Vrátí přímé potomky podle $where */
		function getChildrenWhere($where, cView $view)
		{
			$nodes = array();
			if (is_numeric($this->id)) {
				$nodes = $this->cms->tree->getNodes("parent_id=".$this->id." AND ".$where, $view);
			}
			return $nodes;
		}
	
		/** Vrátí všechny potomky podle $where */
		function getSubNodesWhere($where, cView $view)
		{
			$nodes = array();
			if (is_numeric($this->id) && is_numeric($this->lft) && is_numeric($this->rgt)) 
			{
				$nodes = $this->cms->tree->getNodes("lft>".$this->lft." AND rgt<".$this->rgt." AND ".$where, $view);
			} else throw new cException("node ".get_class($this)." nemá id, lft, nebo rgt");
			
			return $nodes;
		}


		/* =========================== */
		/* ---- manipulace s node ---- */
		/* =========================== */


		function refresh() 
		{

			if (is_numeric($this->id)) 
			{
				try {
					$tables = $this->getTables();
					$sxml=$this->cms->tree->getSXML($tables,$tables[0].".id=".$this->id);
					$this->setData($sxml[0]);
				} catch (Exception $e) {
					throw $e; 
				}
			} $this->cms->debugger->warning("Chlapeček ".get_class($this)." nemá id.");
		}
		
		
		function complete(cView $view = null) 
		{
			//	získat definici, pokud chybí a constructnout svůj part
			if ($this->definition === null) { $this->setDefinition($this->getDefinition($view)); }

			if (is_numeric($this->id)) 
			{
				$table = $this->getTables();
				
				if (count($table)>count($this->data->children())) {
					$this->refresh();
				}
			}
		}
		
		
		/* ==== Akce ==== */
		
		function publish($startTransaction=true)
		{
			try {
				$this->setStandard("visibility","published");
				$this->_save(false);
			} catch (Exception $e) {
				throw $e;
			}
		}

		function unpublish($startTransaction=true)
		{
			try {
				$this->setStandard("visibility","not-published");
				$this->_save(false);
			} catch (Exception $e) {
				throw $e;
			}
		}
	
		function makePrivate($startTransaction=true)
		{
			try {
				$this->setStandard("visibility","private");
				$this->_save($startTransaction);
			} catch (Exception $e) {
				throw $e;
			}
		}
	
	
		function delete($startTransaction=true, cView $view)
		{
			try {
				$this->beforeDelete();
				$this->_delete($startTransaction, $view);
				$this->afterDelete();
			} catch (Exception $e) {
				throw $e;
			}			
		} 

		function recycle($startTransaction=true)
		{
			try {
				$this->beforeRecycle();			
				$this->setStandard("recycled","1");
				$this->_save($startTransaction);
				$this->afterRycycle();			
			} catch (Exception $e) {
				throw $e;
			}		
		} 

		function moveTo($parent_id, $startTransaction=true)
		{
			try {
				$this->setStandard("parent_id",$parent_id);
				$this->save($startTransaction);
			} catch (Exception $e) {
				throw $e;
			}
		}

		function changeOwner($newOwner, $recursively)
		{
		}
		function changeGroup($newGroup, $recursively)
		{
		}
		function changeMode($newMode,$recursively)
		{
		}
		
		/* =============================== */
		/* funkce pro rychlou práci s node */
		/* =============================== */

		function select($where="1") 
		{
			if (!isset($this->group) || !isset($this->type)) {
				$info = explode("_",substr(get_class($this),1)); 
				$this->group = $info[0];
				$this->type = $info[1];
			}
			$thisTable=strToLower($this->cms->tree->prefix.$this->group."_".$this->type);
			$arr = $this->cms->tree->query("SELECT * FROM ".$thisTable." WHERE $where");
			return $arr;
		}

		protected function update($set, $where=null) 
		{
			if (!isset($this->group) || !isset($this->type)) {
				$info = explode("_",substr(get_class($this),1)); 
				$this->group = $info[0];
				$this->type = $info[1];
			}

			if ($where===null) $where = "id = ".$this->id;
			$thisTable=strToLower($this->cms->tree->prefix.$this->group."_".$this->type);
			return $this->cms->tree->query("UPDATE ".$thisTable." SET $set  WHERE $where");
		}
	
		function getUrl($view, $override=array()) 
		{
			if ($this->id === null) 
			{
				$this->cms->debugger->warning("Chlapeček ".get_class($this)." nemá id.");
			} else {
				return $view->getUrl(array_merge(array('id'=>$this->id), $override));
			}
		}
	

	/* =========================================== */
	/* ------- manipulace s datama nodeu --------- */
	/* =========================================== */
	
	function setStandard($name,$val) 
	{
		$this->{$name} = $this->data->standard_treeitem->{$name} = $val;
	}
	
	function setCustom($name,$val) 
	{
		$this->data->{$this->group.'_'.$this->type}->{$name}=$val;
	}
	
	function getStandard($name) 
	{
		return (string)$this->data->standard_treeitem->{$name};
	}

	function getCustom($name) 
	{
		$n = $this->data->{$this->group.'_'.$this->type}->{$name};
		return (string)$n;
	}
	
	
	function setData($data = null)
	{	
		$default = '<node />';
		if ($data === null) { $data = $default; }
		
		if (is_object($data)) 
		{
			if ($data instanceof SimpleXMLElement) 
			{
				$this->data = $data;
			} else throw new cException("data nemůže být ".get_class($data));
		} else $this->data = simplexml_load_string($data);	
		
		if ($data != $default)
		$this->onDataLoad();
	}
	
	function getSXML(SimpleXMLElement $inSXML, cView $view, SimpleXMLElement $outSXML=null)
	{

		if ($outSXML === null) $outSXML = simplexml_load_string('<?xml version="1.0" encoding="UTF-8" ?><node />');
		
		$this->setSXML($inSXML, $view, $outSXML);
		
		return $outSXML;
	}
	
	/**
	 * Pro kustomizace podědit a tuhle přepsat 
	 */
	function setSXML(SimpleXMLElement $inSXML, cView $view, SimpleXMLElement $outSXML) 
	{
		
		//	získat data, pokud chybí	
		if ($inSXML === null)	{ $inSXML = $this->getDefaultData(); }
		
		$this->documentElement->setSXML($inSXML, $view, $outSXML);
	}
	
	function getDefaultData() 
	{
		// TODO : přepsat na něco inteligentnějšího?
		return simplexml_load_string('<?xml version="1.0" encoding="UTF-8" ?><node />');
	}

	

	/* =========================================== */
	/*  manipulace s datama nodeu (interní rutiny) */
	/* =========================================== */

	function save($startTransaction = true) 
	{
		try {
			$this->beforeSave();
			$this->_save($startTransaction);
			$this->afterSave();
		} catch (Exception $e) {
			throw $e;
		}
	}

	/** Uloží node (zjistí, zda insert/update a provede)*/
	protected function _save($startTransaction)
	{
		try {
			$this->_update($startTransaction);
		} catch (Exception $e) {
			throw $e;
		}
	}
	
	
	protected function _move($from, $toID)
	{
		if (1) //$from['parent_id']!=$toID)
		{
			$newParent = $this->cms->tree->selectRaw("id=".$toID, $this->cms->view);
			if ($newParent[0]["lft"]>$from["lft"] && $newParent[0]["rgt"]<$from["rgt"])
			{
				throw new cException("Nelze přemístit do svého potomka!");
			}
			$newPos = $this->cms->nstree->moveToFirstChild($from, $newParent[0]);

			$this->data->standard_treeitem->lft = $newPos["lft"];
			$this->data->standard_treeitem->rgt = $newPos["rgt"];
		}
	}
	/** updatne node */
	protected function _update($startTransaction=true)
	{
		try 
		{
			if ($startTransaction)
			{
				$this->cms->tree->query("SET AUTOCOMMIT=0");
				$this->cms->tree->query("START TRANSACTION");
			}

			// TODO : nekde v event by se mely checknout prava
			
			if (!is_numeric($this->id) && $this->id!==0) 
			{			
				/*  v tehle udalosti se nam predvytvori radky v tabulkach,
				 *	takze pak jenom provedeme update
				 */	
				$this->beforeInsert();
			} else {
				$this->beforeUpdate();
			}

			foreach ($this->data as $key=>$sxml)
			{	
				$table=strToLower($this->cms->tree->prefix.$key);
				
				$set=$this->sxmlToSet($sxml,array());
			
				$this->cms->tree->query($q='UPDATE `'.$table.'` SET '.$set.' WHERE id='.$this->id);
			}
			
			// kvuli cache
			$this->cms->cache->changed($this->id);
			$this->cms->cache->changed($this->parent_id);
			
			if ($startTransaction) 
			{
				$this->cms->tree->query("COMMIT");
			}	
		} catch (Exception $e) {
			$this->cms->tree->query("ROLLBACK");	
			throw $e;		
		}
		
		$this->afterUpdate(); 
	}
	
	protected function _delete($startTransaction=true, cView $view)
	{
		$this->beforeDelete();
		try {
			if ($startTransaction) {
				$this->cms->tree->query("SET AUTOCOMMIT=0");
				$this->cms->tree->query("START TRANSACTION");
			}
			if ($this->hasChildren()) {
				$subNodes=$this->getChildrenWhere("1", $view);
				foreach ($subNodes as $sn) {
					$sn->delete(false, $view);
				}
			}
			
			$table = $this->getTables();
			
			$mainTable = array_shift($table);

			//smazat se
			foreach ($table as $t) {
				$this->cms->tree->query($q="DELETE FROM `".$t."` WHERE id=".$this->id."");
			}

			//smazat se ze stroma
			$this->refresh();
			$this->cms->nstree->delete(array("lft"=>$this->lft, "rgt"=>$this->rgt));
			if ($startTransaction) {
				$this->cms->tree->query("COMMIT");
			}	

			// pro cache
			$this->cms->cache->changed($this->id);
			$this->cms->cache->changed($this->parent_id);
			
			/* Po smazání, pokud se chce user podívat na nás, 
			 * přemístíme ho do svého otce.
			 */
			if ($this->cms->view->id == $this->id) 
			{
				$this->cms->view->id = $this->parent_id;
				
				/*	tohle user očekává, vrátí se do složky,
				 *  která obsahovala tento node a uvidí výpis nodeů
				 */ 
				$this->cms->view->action="show";				
			}
		} catch (Exception $e) {
			$this->cms->tree->query("ROLLBACK");
			throw $e;
			
		} 
		$this->afterDelete();
	}
	
	/* =================================================== */
	/* ----------------- POST HANDLING ------------------- */
	/* =================================================== */
	
	function handlePost($post, cView $view)
	{		
		if (is_array($post["_action"])) {
			foreach ($post["_action"] as $k=>$v) $action=$k;
		}
		
		//echo "will perform $action<br/>";
		
		$a = "handle".$action;
		try {
			if (method_exists($this,$a) && strToLower($action)!="post") {
				$this->$a($post, $view);
			} //else throw new cException("Akce \"$action\" není známa");
		} catch (Exception $e) {
			throw $e;
		}
	}

	
	function handleDelete($post, cView $view)
	{
		try {
			$this->id=$post["standard_treeitem"]['id'];
			$this->refresh();
			$this->delete(true, $view);
		} catch (Exception $e) {
			throw $e;
		}
	}
	
	/** Uloží dom nodeu do DB*/
	function handleSave($post, $view)
	{
		
		// sundá slashe z textu (rekurzivně)
		if (get_magic_quotes_gpc()) {
			$this->rStripValueSlashes($post);
		}		
		
		$this->id = $post['standard_treeitem']['id'];

		$this->complete($view);
		
		//print_r($post);
		
		$data = $this->postToSXML($post);
		
		$view =  new cView(array("action"=>"show","lang"=>$post["lang"],"doctype"=>"raw","mode"=>"backend"), $this->cms->defaultView);

		$outSXML = $this->getSXML($data, $view);
		
		//echo $outSXML->asXML();
		//die();
		
		$this->setData($outSXML);
		$this->save();
	}
	
	function postToSXML($post,$parent=null) 
	{
		if ($parent===null) { $parent=simplexml_load_string('<?xml version="1.0" encoding="UTF-8" ?><node />'); }
		
		foreach ($post as $key=>$val) 
		{
			if (is_array($val)) {
				$this->postToSXML($val,$parent->addChild($key)); 
			} else {
				$parent->addChild($key,htmlspecialchars($val));				
			}
		}
		return $parent;
	}
	

	function handlePlace($post, $view) 
	{
		$dest = $this->cms->tree->getRaw("id=".$post["destination"], $view);
		$dest = $dest[0];
		$rel = strToLower($post["rel"]);
		//print_r($post);
		
		if ($rel=="before") {
			$this->cms->nstree->MoveToPrevSibling(array("lft"=>$this->lft,"rgt"=>$this->rgt), $dest);
		} else if ($rel=="after") {		
			$this->cms->nstree->MoveToNextSibling(array("lft"=>$this->lft,"rgt"=>$this->rgt), $dest);
		}
	}
	
	
	/* ===================================== */
	/* ----------- pomocné kraviny --------- */
	/* ===================================== */
	
	function __toString() 
	{
		$s.=print_r(array('vars'=>get_object_vars($this)),false);
		return $s;
	}

	/**
	 * Post array převede do elementu domu
	 */
	function postToElm($post,$name,$dom) 
	{
		$node = null;
		if (is_array($post)) {
			$node = $dom->createElement($name);
			foreach ($post as $name=>$val) {
				$e=$this->postToElm($val,$name,$dom);
				if ($e!=null) {
				$node->appendChild($e);
				}
			}
		} else if ($name!="") $node = $dom->createElement($name,htmlspecialchars($post, null, "utf-8"));
		
		return $node;
	}

	private function sxmlToSet($elm, $exclude=array())
	{
		$s = array();
		foreach ($elm as $name=>$val) 
		{
			if (!in_array($name,$exclude)) 
			{
				if ($val=='NULL' || $val==null) 
				{
					$s[]='`'.$name.'`=NULL';
				} else $s[]='`'.$name.'`=\''.mysql_real_escape_string((string)$val).'\'';
			}
		}
		return implode(', ',$s);
	}
	
	private function makeStringId()
	{		
		$title = (string)$this->data->standard_treeitem->name;
		$id = $this->id;
		
		$sid2=$sid=$this->toSafeChars($title);
		
		$i=2;
		$r=$this->cms->tree->query("SELECT id,string_id FROM `".$this->cms->table->prefix."standard_treeitem` WHERE string_id LIKE '".$sid."%' ORDER BY string_id ASC");
		while ($found=mysql_fetch_array($r)) {
			if ($found["string_id"]==$sid2) {
				if ($found["id"]==$id) {
					return $sid;
				} else $sid2=$sid."-".$i++;
			} else return $sid2;
		}
		return $sid2;
	}
	
	function toSafeChars($title) 
	{
	    $cz=array("ý","Č","Ď","Ň","Ř","Š","Ť","Ö","Ú","Ë","Ž","Ů","Ä","á","é","í","ó","č","ů","ď","ú","ě","ň","ü","ř","ö","š","ë","ť","ů","ž");
    	$en=array("y","c","d","n","r","s","t","o","u","e","z","u","a","a","e","i","o","c","u","d","u","e","n","u","r","o","s","e","t","u","z");
		$title=str_replace($cz,$en,$title);

		$title=preg_replace("/&[^;]*;/","",$title);
		$title=htmlentities($title);
		$title=preg_replace("/&[^;]*;/","",$title);

	    $title=eregi_replace('[^a-z0-9_]', '-', $title);
    	$title=preg_replace("/(-){2,}/","\\1", $title);

	    if (mb_substr($title,mb_strlen($title)-1,1)=="-") {
      		$title=mb_substr($title,0,-1);
	    }
	    return strToLower($title);
	}

	function rStripValueSlashes(&$array) {
		foreach ($array as $k=>$v) {
			if (is_array($v)) {
				$this->rStripValueSlashes($array[$k]);
			} else $array[$k]=stripslashes($v);
		}
	}
	

}


?>